The searchBox widget lets users perform a text-based query.

The search box is usually the main entry point to start the search on an InstantSearch page. It’s usually placed at the top of a search experience, so users can start searching right away.

searchBox({
    container,
    // Optional parameters
    placeholder,
    autofocus,
    ignoreCompositionEvents,
    searchAsYouType,
    showReset,
    showSubmit,
    showLoadingIndicator,
    queryHook,
    templates,
    cssClasses
});

Options

container
string
required

The CSS selector or HTML element to insert the widget into.

searchBox({
    container: '#searchbox',
});
placeholder
string

The placeholder text of the input.

searchBox({
    // ...
    placeholder: 'Search for products',
});
autofocus
boolean
default:"false"

Whether to automatically focus on the input when rendered.

searchBox({
    // ...
    autofocus: true,
});
ignoreCompositionEvents
boolean
default:"false"

Whether to update the search state in the middle of a composition session. This is useful when users need to search using non-Latin characters.

searchBox({
    // ...
    ignoreCompositionEvents: true,
});

Available from v4.64.2.

searchAsYouType
boolean
default:"true"

Whether to make a search on every change to the query. If false, new searches are only triggered by clicking the submit button or by pressing the Enter key in the search box.

searchBox({
    // ...
    searchAsYouType: false,
});
showSubmit
boolean
default:"false"

Whether to show the submit button.

searchBox({
    // ...
    showSubmit: false,
});
showReset
boolean
default:"false"

Whether to show the reset button.

searchBox({
    // ...
    showReset: false,
});
showLoadingIndicator
boolean
default:"true"

Whether to show the loading indicator (replaces the submit button if the search is stalled).

searchBox({
    // ...
    showLoadingIndicator: false,
});
queryHook
function

A function that’s called just before the search is triggered. It takes two parameters:

  • query: string: the current query string
  • search: function: a function to trigger the search.

If the search method isn’t called, no search is made to Algolia and the UI doesn’t refresh. If the search method is called, the widget is rendered.

This can be useful if you need to:

  • Debounce searches to regulate requests.
  • Programmatically alter the query before sending it to Algolia.
searchBox({
    // ...
    queryHook(query, search) {
    search(query);
    },
});
templates
object

The templates to use for the widget.

searchBox({
    // ...
    templates: {
    // ...
    },
});

You can customize parts of the widget’s UI with templates.

Every template provides an html function you can use as a tagged template. Using html lets you safely provide templates as an HTML string. It works directly in the browser without a build step. See more information, see Templating your UI.

The html function is available from InstantSearch v4.46.0.

Template parameters

submit
string (deprecated) or function
default:"true"

The template used for displaying the submit button.

searchBox({
    // ...
    templates: {
    submit({ cssClasses }, { html }) {
        return html`<span class="${cssClasses.submit}">submit</span>`;
    },
    },
});
reset
string (deprecated) or function
default:"true"

The template used for displaying the reset button.

searchBox({
    // ...
    templates: {
    reset({ cssClasses }, { html }) {
        return html`<span class="${cssClasses.reset}">reset</span>`;
    },
    },
});
loadingIndicator
string (deprecated) or function
default:"true"

The template used for displaying the loading indicator.

searchBox({
    // ...
    templates: {
    loadingIndicator({ cssClasses }, { html }) {
        return html`<span class="${cssClasses.loadingIndicator}">loading</span>`;
    },
    },
});
cssClasses
object

The CSS classes you can override:

  • root: the root element of the widget.
  • form: the form element.
  • input: the input element.
  • reset: the reset button element.
  • resetIcon: the reset button icon.
  • loadingIndicator: the loading indicator element.
  • loadingIcon: the loading indicator icon.
  • submit: the submit button element.
  • submitIcon: the submit button icon.
searchBox({
    // ...
    cssClasses: {
    root: 'MyCustomSearchBox',
    form: [
        'MyCustomSearchBoxForm',
        'MyCustomSearchBoxForm--subclass',
    ],
    },
});

HTML output

HTML
<div class="ais-SearchBox">
<form class="ais-SearchBox-form" novalidate>
    <input class="ais-SearchBox-input" autocomplete="off" autocorrect="off" autocapitalize="off" placeholder="Search for products" spellcheck="false" maxlength="512" type="search" value="" />
    <button class="ais-SearchBox-submit" type="submit" title="Submit the search query.">
    <svg class="ais-SearchBox-submitIcon" xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 40 40">
        ...
    </svg>
    </button>
    <button class="ais-SearchBox-reset" type="reset" title="Clear the search query." hidden>
    <svg class="ais-SearchBox-resetIcon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="10" height="10">
        ...
    </svg>
    </button>
    <span class="ais-SearchBox-loadingIndicator" hidden>
    <svg width="16" height="16" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="#444" class="ais-SearchBox-loadingIcon">
        ...
    </svg>
    </span>
</form>
</div>

Connector

To create your own UI for the searchBox widget, use the connectSearchBox comnector.

Import it with a package manager or with a CDN.

import { connectConfigure } from 'instantsearch.js/es/connectors';

After importing:

1

Create a render function

This rendering function is called before the first search (init lifecycle step) and each time results come back from Algolia (render lifecycle step).

const renderSearchBox = (renderOptions, isFirstRender) => {
    // Rendering logic
};

Render options

query
string

The query from the current search.

const renderSearchBox = (renderOptions, isFirstRender) => {
const { query, refine } = renderOptions;

const container = document.querySelector('#searchbox');

if (isFirstRender) {
    const input = document.createElement('input');

    input.addEventListener('input', event => {
    refine(event.target.value);
    });

    container.appendChild(input);
}

container.querySelector('input').value = query;
};
refine
function

Sets a new query and triggers a new search.

const renderSearchBox = (renderOptions, isFirstRender) => {
const { query, refine } = renderOptions;

const container = document.querySelector('#searchbox');

if (isFirstRender) {
    const input = document.createElement('input');

    input.addEventListener('input', event => {
    refine(event.target.value);
    });

    container.appendChild(input);
}

container.querySelector('input').value = query;
};
clear
function

Removes the query and triggers a new search.

const renderSearchBox = (renderOptions, isFirstRender) => {
const { query, refine, clear } = renderOptions;

const container = document.querySelector('#searchbox');

if (isFirstRender) {
    const input = document.createElement('input');
    const button = document.createElement('button');
    button.textContent = 'X';

    input.addEventListener('input', event => {
    refine(event.target.value);
    });

    button.addEventListener('click', () => {
    clear();
    });

    container.appendChild(input);
    container.appendChild(button);
}

container.querySelector('input').value = query;
};
isSearchStalled
boolean

Returns true if the search results take more than a certain time to come back from Algolia servers. This can be configured on the instantsearch constructor with the attribute stalledSearchDelay.

const renderSearchBox = (renderOptions, isFirstRender) => {
const { query, refine, isSearchStalled } = renderOptions;

const container = document.querySelector('#searchbox');

if (isFirstRender) {
    const input = document.createElement('input');
    const loadingIndicator = document.createElement('span');
    loadingIndicator.textContent = 'Loading...';

    input.addEventListener('input', event => {
    refine(event.target.value);
    });

    container.appendChild(input);
    container.appendChild(loadingIndicator);
}

container.querySelector('input').value = query;
container.querySelector('span').hidden = !isSearchStalled;
};
widgetParams
object

All original widget options forwarded to the render function.

const renderRangeInput = (renderOptions, isFirstRender) => {
const { widgetParams } = renderOptions;

widgetParams.container.innerHTML = '...';
};

// ...

search.addWidgets([
customRangeInput({
    container: document.querySelector('#searchbox'),
})
]);
2

Create the custom widget

When creating and instantiating a custom widget, there are two types of parameters you can give:

  • Instance parameters: predefined parameters that you can use to configure the behavior of Algolia.
  • Your own parameters: to make the custom widget generic.

Both instance and custom parameters are available in connector.widgetParams, inside the renderFunction.

const customSearchBox = connectSearchBox(
    renderSearchBox
);
3

Instantiate

customSearchBox({
queryHook(query, search) {
    search(query);
},
});

Instance options

queryHook
function

Use this is the same way as the queryHook option.

Connector example

// Create a render function
const renderSearchBox = (renderOptions, isFirstRender) => {
    const { query, refine, clear, isSearchStalled, widgetParams } = renderOptions;

    if (isFirstRender) {
    const input = document.createElement('input');

    const loadingIndicator = document.createElement('span');
    loadingIndicator.textContent = 'Loading...';

    const button = document.createElement('button');
    button.textContent = 'X';

    input.addEventListener('input', event => {
        refine(event.target.value);
    });

    button.addEventListener('click', () => {
        clear();
    });

    widgetParams.container.appendChild(input);
    widgetParams.container.appendChild(loadingIndicator);
    widgetParams.container.appendChild(button);
    }

    widgetParams.container.querySelector('input').value = query;
    widgetParams.container.querySelector('span').hidden = !isSearchStalled;
};

// Create custom widget
const customSearchBox = connectSearchBox(
    renderSearchBox
);

// Instantiate custom widget
search.addWidgets([
    customSearchBox({
    container: document.querySelector('#searchbox'),
    })
]);